//package com.hlkj.warboot.configurer.transaction;
//
//import org.aspectj.lang.annotation.Aspect;
//import org.springframework.aop.Advisor;
//import org.springframework.aop.aspectj.AspectJExpressionPointcut;
//import org.springframework.aop.support.DefaultPointcutAdvisor;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.stereotype.Component;
//import org.springframework.transaction.TransactionDefinition;
//import org.springframework.transaction.TransactionManager;
//import org.springframework.transaction.interceptor.DefaultTransactionAttribute;
//import org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource;
//import org.springframework.transaction.interceptor.TransactionInterceptor;
//
//import javax.annotation.Resource;
//
///**
// * @Description: TODO 基于AOP的事务管理配置
// * @Author: 李星 lixing_java@163.com
// * @Date: 2020/2/19 20:22
// */
//@Aspect
//@Configuration
//@Component
//public class TransactionConfig {
//    // 定义切面，控制事务拦截范围
//    private static final String AOP_POINTCUT_EXPRESSION = "execution (* com.hlkj.warboot.*.service.impl.*.*(..))";
//
//    // 事务管理器
//    @Resource
//    private TransactionManager transactionManager;
//    //private PlatformTransactionManager transactionManager; // Springboot2.2.6中该方式已废弃，不推荐使用
//
//    /*
//     * 事务通知
//     *   propagation(传播行为):
//     *      MANDATORY: 如果已经存在一个事务，支持当前事务。如果没有一个活动的事务，则抛出异常
//     *      NESTED: 如果一个活动的事务存在，则运行在一个嵌套的事务中. 如果没有活动事务, 则按TransactionDefinition.PROPAGATION_REQUIRED 属性执行。
//     *      NEVER: 总是非事务地执行，如果存在一个活动事务，则抛出异常
//     *      NOT_SUPPORTED:  总是非事务地执行，并挂起任何存在的事务
//     *      REQUIRED: 如果存在一个事务，则支持当前事务。如果没有事务则开启
//     *      REQUIRES_NEW: 总是开启一个新的事务。如果一个事务已经存在，则将这个存在的事务挂起
//     *      SUPPORTS: 如果存在一个事务，支持当前事务。如果没有事务，则非事务的执行
//     *  isolation(隔离级别):
//     *      DEFAULT: 默认的隔离级别，使用数据库默认的事务隔离级别
//     *      READ_UNCOMMITTED: 是最低的事务隔离级别，它允许另外一个事务可以看到这个事务未提交的数据
//     *      READ_COMMITTED: 保证一个事物提交后才能被另外一个事务读取。另外一个事务不能读取该事物未提交的数据
//     *      REPEATABLE_READ: 这种事务隔离级别可以防止脏读，不可重复读。但是可能会出现幻象读。它除了保证一个事务不能被另外一个事务读取未提交的数据之外还避免了以下情况产生（不可重复读）
//     *      SERIALIZABLE: 避免以上所有读问题
//     */
//    @Bean
//    public TransactionInterceptor txAdvice() {
//        DefaultTransactionAttribute transactionAttribute_REQUIRED = new DefaultTransactionAttribute();
//        transactionAttribute_REQUIRED.setPropagationBehavior( TransactionDefinition.PROPAGATION_REQUIRED); // 传播行为
//        transactionAttribute_REQUIRED.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED); // 隔离级别
//
//        DefaultTransactionAttribute transactionAttribute_REQUIRED_READONLY = new DefaultTransactionAttribute();
//        transactionAttribute_REQUIRED_READONLY.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); // 传播行为
//        transactionAttribute_REQUIRED_READONLY.setReadOnly(true);
//        transactionAttribute_REQUIRED_READONLY.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED); // 隔离级别
//
//        NameMatchTransactionAttributeSource nameMatchTransactionAttributeSource = new NameMatchTransactionAttributeSource();
//        nameMatchTransactionAttributeSource.addTransactionalMethod("insert*", transactionAttribute_REQUIRED);
//        nameMatchTransactionAttributeSource.addTransactionalMethod("delete*", transactionAttribute_REQUIRED);
//        nameMatchTransactionAttributeSource.addTransactionalMethod("update*", transactionAttribute_REQUIRED);
//        nameMatchTransactionAttributeSource.addTransactionalMethod("select*", transactionAttribute_REQUIRED_READONLY);
//
//        return new TransactionInterceptor(transactionManager, nameMatchTransactionAttributeSource);
//    }
//
//    // 通过AOP拦截功能将事务（txAdvice）加载到服务层中的所有方法上
//    @Bean
//    public Advisor txAdviceAdvisor() {
//        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
//        pointcut.setExpression(AOP_POINTCUT_EXPRESSION);
//        return new DefaultPointcutAdvisor(pointcut, txAdvice());
//    }
//
//}